package cn.jbolt.ec.order;

import cn.jbolt.common.model.*;
import cn.jbolt.ec.member.MemberService;
import cn.jbolt.ec.wx.GenService;
import com.alibaba.fastjson.JSON;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Kv;

import java.util.HashMap;
import java.util.Map;

public class PayService {
    @Inject
    RetailerMemberBalanceService bservice;
    @Inject
    MemberCouponService cservice;
    @Inject
    MemberService mservice;
    @Inject
    OrderService oservice;
    @Inject
    OrderMsgService orderMsgService;

    @Inject
    RetailerMemberBalanceService retailerMemberBalanceService;


    private static WxPayConfig payConfig;
    private static BecApp becApp;
    private static WxPayService wxPayService;

    static{
        System.out.println("static wechat");
        BecApp becApp = GenService.getApp();
        payConfig=new WxPayConfig();

        payConfig.setAppId(becApp.getAppid());
        payConfig.setMchId(becApp.getAppPayId());
        payConfig.setMchKey(becApp.getAppPaySecret());
        payConfig.setNotifyUrl(becApp.getAppPayCallbackRul());
        payConfig.setTradeType("JSAPI");

        wxPayService=new WxPayServiceImpl();
        wxPayService.setConfig(payConfig);

    }


    /**
     * 订单支付预备
     * @param
     * @param
     * @param
     * @return
     */

    public static Map<String, Object> gen_param(String openid, int pay_amount,
                                                String order_str, String msg,
                                                String ips){
        Map<String, Object> resultMap = new HashMap<>();
        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
        //支付信息
        orderRequest.setBody(msg);
        //用户openid
        orderRequest.setOpenid(openid);
        //支付金额
        orderRequest.setTotalFee(pay_amount);   //注意：传入的金额参数单位为分
        //outTradeNo  订单号
        orderRequest.setOutTradeNo(order_str);
        //用户IP地址
        orderRequest.setSpbillCreateIp(ips);
        Map<String, Object> payparams = new HashMap<>();
        try{
            if (pay_amount > 0){
                Object obj  = wxPayService.createOrder(orderRequest);
                payparams= JSON.parseObject(JSON.toJSONString(obj), Map.class);
                payparams.put("package",payparams.get("packageValue"));
            }

            resultMap.put("payParams", payparams);
            resultMap.put("order_id",order_str);//订单号
            resultMap.put("pay_amount", pay_amount);//支付金额
            resultMap.put("ok",true);
        }catch (WxPayException e){
            System.out.println(e.getMessage());

        } catch(Exception e){
            System.out.println(e.getMessage());

        }
        if(resultMap.isEmpty()){
            resultMap.put("msg","订单初始化失败");
        }
        return resultMap;
    }

    /**
     *
     * @param order_id
     * @param coupon_id
     * @param use_balance
     * @param openid
     * @return
     */

    public BecRetailerOrder check(int order_id,
                                  int coupon_id,
                                  boolean use_balance,
                                  String openid){


        BecRetailerOrder order = oservice.findById(order_id);
        BecMember m = mservice.findById(order.getClientId());
        if(m==null || !m.getOpenidJmd().equals(openid)){
            order.setId(-1);
            return order;
        }
        //  防止重复结账、扣余额
        if(order.getStatus()>5) {
            order.setId(-1);
            return order;
        }
        int type = order.getType();

        /**
         * 保证充值不使用现金或余额
         *
         */
        if(type==3){
            coupon_id=0;
            use_balance = false;
        }

        order.setCashAmount(0).setBalanceAmount(0).setRetailerBalanceAmount(0);
        BecMemberCoupon coupon = coupon_id==0? null : cservice.findById(coupon_id);
        BecRetailer becRetailer = new BecRetailer().dao().findByIdLoadColumns(order.getRetailerId(),
                "discount,platform_commission,spreader_credit");


        long x = order.getAmountPaid();
        order.setCouponAmount(0);


        if(coupon!=null && !coupon.getUsed()){
            int face_value = coupon.getFaceValue();
            if(face_value<x/4){

                x -= face_value;
                // 不控制使用才需要,当前已经控制
                // if(x<0) x=0;
                coupon.setUsed(true);
                coupon.update();
                order.setCouponAmount(face_value);
                order.setCouponId(coupon_id);
            }

        }

        if(use_balance && x>0){
            Kv cond = Kv.by("member_id",order.getClientId())
                    .set("retailer_id",order.getRetailerId());

            BecRetailerMemberBalance mb = bservice.findFirst(cond);

            if(mb!=null ){

                // 使用商家余额
                if(!(mb.getBalance()<x)){
                    mb.setBalance((int)(mb.getBalance()-x));
                    if(!mb.update()){

                    }
                    order.setRetailerBalanceAmount((int)x);

                    x=0; // 无需再支付

                }else{
                    // 使用全部余额
                    int z =mb.getBalance();
                    x -= z;
                    mb.setBalance(0);
                    if(!mb.update()){

                    }
                    order.setRetailerBalanceAmount(z);

                }

            }

            long y = m.getBalance();
            if(y>0 && x>0){
                if(!(y<x)) {
                    m.setBalance(y - x);
                    m.update();
                    order.setBalanceAmount((int)x);
                    x=0;
                }else{

                    m.setBalance(0L);
                    m.update();
                    order.setBalanceAmount((int)y);

                    x -= y;
                }

            }



        }


        order.setCashAmount((int)x);


        if(m==null) return null;






        // 无需支付现金

        if(x==0){
            // 执行支付后处理
            Integer spreader_id = m.getSpreaderId();

            if(spreader_id==null) spreader_id = 0;

            handle_typeAB(order,spreader_id);

            // 余额支付完毕
            order.setStatus(7);


        }else{

            order.setStatus(6);
        }

        order.update();




        return order;

    }



    public String paid_handle(String result){
        WxPayOrderNotifyResult payResult;
        String tradeNo="";
        Integer fee;
        try{
             payResult = wxPayService.parseOrderNotifyResult(result);
             tradeNo = payResult.getTransactionId();
             fee = payResult.getCashFee().intValue();


        }catch (Exception e){
            return "fail";

        }


        /**
         * 判断order状态，若还是未支付状态，执行如下
         */
        System.out.println("result:"+result);
        String orderId = payResult.getOutTradeNo();


        Kv cond = Kv.by("order_id",orderId);
        BecRetailerOrder becRetailerOrder = oservice.findFirst(cond);
        // 微信交易号
        becRetailerOrder.setTransactionid(tradeNo);

        if(becRetailerOrder.getStatus()>6){
            return "done";
        }
        becRetailerOrder.setStatus(8);
        BecMember m = new BecMember().dao().findByIdLoadColumns(
                becRetailerOrder.getClientId(),"id,spreader_id,balance");


        int spreader_id =0;
        if(m!=null){
            Integer ix = m.getSpreaderId();
            if(ix!=null && ix>0){
                spreader_id = ix;

            }

        }

        becRetailerOrder.update();
        int orderType = becRetailerOrder.getType();

        if(orderType==1 || orderType==2){
            return handle_typeAB(becRetailerOrder,spreader_id);
        }
        /**
         * 商家充值
         */
        if(orderType==3 ){
            BecRetailerChargeBonus chargeBonus =
                    new BecRetailerChargeBonus().dao()
                            .findById(becRetailerOrder.getChargeId());

            cond = Kv.by("member_id",m.getId()).set("retailer_id",becRetailerOrder.getRetailerId());


            System.out.println("c 1");
            BecRetailerMemberBalance becRetailerMemberBalance =
                    retailerMemberBalanceService.findFirst(cond);
            if(becRetailerMemberBalance==null){
                becRetailerMemberBalance = new BecRetailerMemberBalance();
                becRetailerMemberBalance.setMemberId(m.getId())
                        .setRetailerId(becRetailerOrder.getRetailerId())
                        .setBalance(0).setChargeBonus(0).save();
            }
            becRetailerMemberBalance.setBalance(chargeBonus.getAmount()
                    +becRetailerMemberBalance.getBalance());

            /**
             * 送券
             */
            if(chargeBonus.getStatus()==1){
                System.out.println("c 2");
                handle_typeC(becRetailerOrder,m,chargeBonus);

            }

            becRetailerMemberBalance.update();

        }
        /**
         * 平台充值 typeE
         */
        if(orderType==5){
            System.out.println("test charge");
            Long bl = m.getBalance();

            if(bl==null) bl = 0L;
            m.setBalance(bl+fee);
            m.update();
        }

        return "success";


    }

    /**
     * 支付成功
     * @param becRetailerOrder
     * @param spreader_id
     * @return
     */
    private String handle_typeAB(BecRetailerOrder becRetailerOrder,
                                int spreader_id){

        int coupon_amount = becRetailerOrder.getCouponAmount();
        long amount_total = becRetailerOrder.getAmountTotal();
        // 为了
        long t =1000000L;
        if(coupon_amount>0){
            t =  (amount_total-coupon_amount)*1000000L/amount_total;
        }
        long commission_t = becRetailerOrder.getCommission()*t/1000000L;
        long credit_t = becRetailerOrder.getCredit()*t/1000000L;

        if(spreader_id>0){
            BecMember m= new BecMember().dao().findByIdLoadColumns(
                    spreader_id,"id,spreader_credit");
            m.setSpreaderCredit(m.getSpreaderCredit()+(int)credit_t);
            BecSpreaderCredit becSpreaderCredit = new BecSpreaderCredit();
            becSpreaderCredit.setCredit((int)credit_t)
                    .setOrderId(becRetailerOrder.getId())
                    .setSpreaderId(spreader_id).setOpTime(System.currentTimeMillis()).save();

            m.update();

        }else{
            commission_t+=credit_t;
            credit_t =0;
        }
        BecPlatformCommission becPlatformCommission = new BecPlatformCommission();
        becPlatformCommission.setCommission((int)commission_t);
        becPlatformCommission.setOrderId(becRetailerOrder.getId());
        becPlatformCommission.setOptime(System.currentTimeMillis());
        becPlatformCommission.save();

        // 计算应付给商家的值
        becRetailerOrder.setPayTime(System.currentTimeMillis());
        long x = becRetailerOrder.getBalanceAmount() +
                becRetailerOrder.getRetailerBalanceAmount()+
                becRetailerOrder.getCashAmount()-
                commission_t-credit_t;
        becRetailerOrder.setRetailerAmount((int)x);

        // 简易单直接设置已经送货

        if(becRetailerOrder.getType()==2) becRetailerOrder.setStatus(18);

        becRetailerOrder.update();
        System.out.println(becRetailerOrder);

        // 插入通知模板
        orderMsgService.notify_retailer(becRetailerOrder);
        orderMsgService.notify_spreader(becRetailerOrder);
        orderMsgService.notify_member(becRetailerOrder);

        return "success";
    }


    /**
     * 充值送券
     * @param becRetailerOrder
     * @param becMember
     * @return
     */

    private String handle_typeC(BecRetailerOrder becRetailerOrder,
                                BecMember becMember,
                                BecRetailerChargeBonus chargeBonus){
        //BecMemberCoupon
        int i=0,j;
        int bonus = chargeBonus.getBonus();
        long validms = 365*3600000*24;
        int[] faceValues = new int[]{10000,5000,2000,1000,500,100};
        System.out.println("c 3");
        for(i=0;i<6;i++){
            int x = bonus / faceValues[i];
            bonus = bonus % faceValues[i];
            for(j=0;j<x;j++){
                BecMemberCoupon coupon = new BecMemberCoupon();
                coupon.setUsed(false).setFaceValue(faceValues[i])
                        .setRetailerId(becRetailerOrder.getRetailerId())
                        .setRetailerId(becRetailerOrder.getRetailerId())

                        .setExpired(System.currentTimeMillis()+validms)
                        .setMemberId(becMember.getId()).save();

            }

        }


        return "success";

    }







}
